{ "cells": [ { "cell_type": "markdown", "id": "779c385b-7a17-4489-bece-0c51056be80d", "metadata": {}, "source": [ "# Structured Output with Julia Set Example\n", "\n", "This example shows how to describe 'structured' output data for a `Runner`, that is, output data can have its own internal dimensions.\n", "\n", "Let's start by defining the Julia set equation with 3 extra modifications (``p``, ``A`` and ``phi``) we want to explore:" ] }, { "cell_type": "code", "execution_count": null, "id": "20708c0d-de44-48ac-893c-5b87d172cd85", "metadata": {}, "outputs": [], "source": [ "%config InlineBackend.figure_formats = ['svg']\n", "\n", "from cmath import exp\n", "\n", "import numba as nb\n", "import numpy as np\n", "\n", "import xyzpy as xyz\n", "\n", "\n", "@nb.vectorize(nopython=True)\n", "def _mandel(z0, p, A, phi, limit):\n", " z = z0\n", " while abs(z) < 2:\n", " limit -= 1\n", " z = z**p + A * exp(1.0j * phi)\n", " if limit < 0:\n", " return 0\n", " return limit\n", "\n", "\n", "def mandel(z0, p=2, A=0.7, phi=1.885, limit=100):\n", " m = _mandel(z0, p, A, phi, limit)\n", " return m, np.std(m)" ] }, { "cell_type": "markdown", "id": "1eb60931-5e62-483e-b1c1-16f976074e93", "metadata": {}, "source": [ "Since it is explicitly vectorized, ``mandel`` takes an array of complex numbers ``z0``, and returns\n", "how many iterations, ``m``, each value takes to diverge (or not). Let's pretend we are also interested in the standard deviation of the results so we return that as well.\n", "\n", "Let's set up some constants including the array of complex numbers we want to supply:" ] }, { "cell_type": "code", "execution_count": 2, "id": "26a1efe9-73dd-446c-adfc-a497aa8b11c4", "metadata": {}, "outputs": [], "source": [ "res = 256\n", "L = 150\n", "re_lims, im_lims = (0.2, 0.4), (-0.4, -0.6)\n", "r = np.linspace(*re_lims, res)\n", "i = np.linspace(*im_lims, res)\n", "zs = r.reshape(-1, 1) + 1.0j * i.reshape(1, -1) # turn into grid" ] }, { "cell_type": "markdown", "id": "1bcfaa8d-c667-4f9e-b899-3c0ffdd63d53", "metadata": {}, "source": [ "Now we can describe the function with a `Runner`:" ] }, { "cell_type": "code", "execution_count": 3, "id": "3090e68d-6927-4611-910b-4757c7016ad5", "metadata": {}, "outputs": [], "source": [ "runner = xyz.Runner(\n", " mandel, # The function\n", " var_names=[\"m\", \"m_sdev\"], # The names of its output variables\n", " var_dims={\"m\": [\"re\", \"im\"]}, # The name of the internal dimensions of 'm'\n", " var_coords={\"re\": r, \"im\": i}, # the coordinates of those dimensions\n", " constants={\"limit\": L}, # supply L as a constant\n", " resources={\"z0\": zs}, # supply z0 as a constant, but don't record it\n", ")" ] }, { "cell_type": "markdown", "id": "b4bc297b-3706-4e73-8503-a168f911564f", "metadata": {}, "source": [ "Now let's define the parameter space we are interested in:" ] }, { "cell_type": "code", "execution_count": 4, "id": "ef286d00-9b81-49da-b0d5-406016c9fc3d", "metadata": {}, "outputs": [], "source": [ "combos = {\n", " \"p\": np.linspace(1.9, 2.1, 3),\n", " \"A\": np.linspace(0.7, 0.8, 5),\n", " \"phi\": [1.85, 1.88, 1.91, 1.94, 1.97, 2.0],\n", "}" ] }, { "cell_type": "markdown", "id": "362caba6-d59d-4d1e-87c0-706ab488bdc0", "metadata": {}, "source": [ "We will thus get 5 dimensions in total: the 3 parameters in ``combos``, and the two internal dimensions ``re`` and ``im``.\n", "\n", "Since each run might be quite slow, let's also parallelize over the runs:" ] }, { "cell_type": "code", "execution_count": 5, "id": "f953b906-7b57-4432-ad14-184992816cd3", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "100%|##########| 90/90 [00:03<00:00, 25.77it/s]\n" ] }, { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.Dataset> Size: 47MB\n",
       "Dimensions:  (p: 3, A: 5, phi: 6, re: 256, im: 256)\n",
       "Coordinates:\n",
       "  * p        (p) float64 24B 1.9 2.0 2.1\n",
       "  * A        (A) float64 40B 0.7 0.725 0.75 0.775 0.8\n",
       "  * phi      (phi) float64 48B 1.85 1.88 1.91 1.94 1.97 2.0\n",
       "  * re       (re) float64 2kB 0.2 0.2008 0.2016 0.2024 ... 0.3984 0.3992 0.4\n",
       "  * im       (im) float64 2kB -0.4 -0.4008 -0.4016 ... -0.5984 -0.5992 -0.6\n",
       "Data variables:\n",
       "    m        (p, A, phi, re, im) int64 47MB 0 0 0 0 0 0 ... 117 118 118 120 120\n",
       "    m_sdev   (p, A, phi) float64 720B 55.42 54.35 50.1 ... 9.138 8.667 10.83\n",
       "Attributes:\n",
       "    limit:    150
" ], "text/plain": [ " Size: 47MB\n", "Dimensions: (p: 3, A: 5, phi: 6, re: 256, im: 256)\n", "Coordinates:\n", " * p (p) float64 24B 1.9 2.0 2.1\n", " * A (A) float64 40B 0.7 0.725 0.75 0.775 0.8\n", " * phi (phi) float64 48B 1.85 1.88 1.91 1.94 1.97 2.0\n", " * re (re) float64 2kB 0.2 0.2008 0.2016 0.2024 ... 0.3984 0.3992 0.4\n", " * im (im) float64 2kB -0.4 -0.4008 -0.4016 ... -0.5984 -0.5992 -0.6\n", "Data variables:\n", " m (p, A, phi, re, im) int64 47MB 0 0 0 0 0 0 ... 117 118 118 120 120\n", " m_sdev (p, A, phi) float64 720B 55.42 54.35 50.1 ... 9.138 8.667 10.83\n", "Attributes:\n", " limit: 150" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "runner.run_combos(combos, parallel=True)" ] }, { "cell_type": "markdown", "id": "64a298d4-f947-4c33-a000-093de6863d68", "metadata": {}, "source": [ "Now let's plot the main variable 'm'. Since we can only plot 4 dimensions at once we have to select a value for one dimension first:" ] }, { "cell_type": "code", "execution_count": 6, "id": "2bc872c8-12e7-48b3-a197-0f75ac9be7ce", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "" ], "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "ds = runner.last_ds.sel(p=2.0)\n", "fig, axs = ds.xyz.plot(\n", " x=\"re\",\n", " y=\"im\",\n", " z=\"m\",\n", " col=\"phi\",\n", " row=\"A\",\n", " palette=\"inferno\",\n", ")" ] }, { "cell_type": "markdown", "id": "0cff3d49-620a-408e-b2f1-fc3ed4ffd590", "metadata": {}, "source": [ "We output multiple variables so we can also plot the quantity ``m_sdev``:" ] }, { "cell_type": "code", "execution_count": 7, "id": "4ffb5ae2-cc9f-4163-88ba-c3ac285f84d3", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "" ], "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "fig, axs = runner.last_ds.xyz.plot(\n", " x=\"phi\",\n", " y=\"m_sdev\",\n", " color=\"A\",\n", " marker=\"A\",\n", " col=\"p\",\n", ")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3" } }, "nbformat": 4, "nbformat_minor": 4 }